﻿using System;
using System.Collections.Generic;
using AwesomeEnginePC.Physics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace AwesomeEnginePC.Graphics.TwoDimensional.Sprites
{
    //public enum ImageRotatorTransitionType
    //{
    //    None = 0,
    //    LinearFade,
    //    Wipe,
    //}

    //public enum ImageRotatorStatus
    //{
    //    Stopped,
    //    ShowingImage,
    //    Transitioning
    //}

    public class SpriteRotator : Base2DObject
    {
        private List<BaseSprite> _imageList;

        //private int _imageIndexToFadeFrom;
        //private int _imageIndexToFadeTo;
        private int _currentImageIndex;

        private bool _isRunning;

        private TimeSpan _previousShowingImageTime;

        //private TimeSpan _previousTransitionTime;
        private TimeSpan _timeBetweenSprites;

        //private byte alphaForFromImage;
        //private byte alphaForToImage;

        /// <summary>
        /// Gets or sets if the rotator will loop when it is complete.
        /// </summary>
        public bool WillLoop { get; set; }

        //public ImageRotatorTransitionType TransitionType { get; set; }
        //private ImageRotatorStatus status { get; set; }

        public int CurrentImageIndex
        {
            get { return _currentImageIndex; }
        }

        public Vector CenterPoint
        {
            get
            {
                return new Vector(Width / 2.0, Height / 2.0);
            }
        }

        public SpriteRotator(ContentManager CM, int width, int height)
            : base(CM)
        {
            _imageList = new List<BaseSprite>();

            //_imageIndexToFadeTo = 1;
            //_imageIndexToFadeFrom = 0;
            _currentImageIndex = 0;
            Width = width;
            Height = height;

            //status = ImageRotatorStatus.Stopped;
            _isRunning = false;
        }

        public void AddImage(string AssetName)
        {
            BaseSprite imageToAdd = new BaseSprite(CM, AssetName);
            imageToAdd.LoadFromSettings(this.GetBase2DObjectSettings());
            _imageList.Add(imageToAdd);
        }

        private void GoToNextImage()
        {
            //_imageIndexToFadeTo += 1;
            //_imageIndexToFadeFrom += 1;
            _currentImageIndex += 1;

            //if (_imageIndexToFadeFrom >= _imageList.Count)
            //    _imageIndexToFadeFrom = 0;

            if (_currentImageIndex >= _imageList.Count)
            {
                if (WillLoop)
                {
                    _currentImageIndex = 0;
                }
                else
                {
                    //status = ImageRotatorStatus.Stopped;
                    _isRunning = false;
                }
            }
        }

        public override int Height
        {
            get;
            set;
        }

        public override int Width
        {
            get;
            set;
        }

        //public void Play(ImageRotatorTransitionType transitionType, TimeSpan timeBetweenSprites, bool willLoop)
        public void Play(TimeSpan timeBetweenSprites, bool willLoop)
        {
            WillLoop = willLoop;

            //TransitionType = transitionType;
            _timeBetweenSprites = timeBetweenSprites;
            _isRunning = true;

            //status = ImageRotatorStatus.ShowingImage;
        }

        public void Stop()
        {
            _isRunning = false;

            //status = ImageRotatorStatus.Stopped;
        }

        private Vector ConvertGlobalOriginToSpriteOrigin(int imageIndex)
        {
            double globOrgPercX = this.Origin.X / Width;
            double globOrgPercY = this.Origin.Y / Height;

            return new Vector(_imageList[imageIndex].RawWidth * globOrgPercX, _imageList[imageIndex].RawHeight * globOrgPercY);
            //_imageList[_currentImageIndex].Origin = newOrigin;
        }

        public override void Update(GameTime gameTime)
        {
            if (_previousShowingImageTime == null)
            {
                _previousShowingImageTime = new TimeSpan(gameTime.TotalGameTime.Ticks);
            }

            //if (_previousTransitionTime == null)
            //{
            //    _previousTransitionTime = new TimeSpan(gameTime.TotalGameTime.Ticks);
            //}

            if (_isRunning)
            {
                //_imageList[_currentImageIndex].LoadFromSettings(this.GetBase2DObjectSettings(), SpriteEffects.None, null);

                //Color fromTint = _imageList[_currentImageIndex].Tint;

                //_imageList[_currentImageIndex].Tint = new Color(fromTint.R, fromTint.G, fromTint.B, _currentImageIndex);
                //_imageList[_currentImageIndex].Height = this.Height;
                //_imageList[_currentImageIndex].Width = this.Width;
                //_imageList[_currentImageIndex].Origin = ConvertGlobalOriginToSpriteOrigin(_currentImageIndex);

                //_imageList[_imageIndexToFadeTo].LoadFromSettings(this.GetBase2DObjectSettings(), SpriteEffects.None, null);
                //Color toTint = _imageList[_imageIndexToFadeTo].Tint;

                //_imageList[_imageIndexToFadeTo].Tint = new Color(toTint.R, toTint.G, toTint.B, alphaForToImage);
                //_imageList[_imageIndexToFadeTo].Height = this.Height;
                //_imageList[_imageIndexToFadeTo].Width = this.Width;
                //_imageList[_imageIndexToFadeTo].Origin = ConvertGlobalOriginToSpriteOrigin(_imageIndexToFadeTo);

                //switch(status)
                //{
                //    case ImageRotatorStatus.ShowingImage:
                //        if (gameTime.TotalGameTime - _previousShowingImageTime >= _timeBetweenSprites)
                //        {
                //            _previousShowingImageTime = new TimeSpan(gameTime.TotalGameTime.Ticks);

                //            //time to go to next image
                //            GoToNextImage();
                //            status = ImageRotatorStatus.Transitioning;
                //            _previousTransitionTime = new TimeSpan(gameTime.TotalGameTime.Ticks);
                //        }
                //        break;
                //    case ImageRotatorStatus.Transitioning:
                //        DoTransitioning(gameTime);
                //        break;
                //}

                if (gameTime.TotalGameTime - _previousShowingImageTime >= _timeBetweenSprites)
                {
                    _previousShowingImageTime = new TimeSpan(gameTime.TotalGameTime.Ticks);

                    //time to go to next image
                    GoToNextImage();

                    //status = ImageRotatorStatus.Transitioning;
                    //_previousTransitionTime = new TimeSpan(gameTime.TotalGameTime.Ticks);
                }
            }
        }

        //private void DoTransitioning(GameTime gameTime)
        //{
        //    TimeSpan timeLeft = (gameTime.TotalGameTime - _previousTransitionTime);

        //    if (timeLeft >= _timeBetweenSprites)
        //    {
        //        //done transitioning
        //        status = ImageRotatorStatus.ShowingImage;
        //    }
        //    else
        //    {
        //        //find percent that it should be finished with, and do that
        //        double percentDone = (double)timeLeft.Ticks / _timeBetweenSprites.Ticks;
        //        switch(TransitionType)
        //        {
        //            case ImageRotatorTransitionType.LinearFade:
        //                DoLinearFade(percentDone);
        //                break;
        //            case ImageRotatorTransitionType.Wipe:

        //                break;
        //        }
        //    }
        //}

        //private void DoLinearFade(double percentageDone)
        //{
        //    //make all pixels in FadeFrom image have an alpha 0 -> 255 depending on the percent done
        //    int alphaValueForAllPixels = (int)(255 * percentageDone);
        //    alphaForToImage = (byte)alphaValueForAllPixels;
        //    alphaForFromImage = (byte)(255 - alphaValueForAllPixels);

        //    //this is apparently wrong. you should be able to set the pixels, but you can only do it once?!?!? yeah.
        //    //well this is good enough for now, but eventually we will want this to work
        //    //Color[] colorsArray = TextureTo2DArray(_imageList[_imageIndexToFadeFrom].SpriteTexture);
        //    //for (int i = 0; i < imageHeight * imageWidth; i++)
        //    //{
        //    //    colorsArray[i].A = (byte)alphaValueForAllPixels;
        //    //}
        //    //_imageList[_imageIndexToFadeFrom].SetTexturePixels(colorsArray);

        //    //Color currentTint = _imageList[_imageIndexToFadeTo].Tint;
        //    //_imageList[_imageIndexToFadeTo].Tint = new Color(currentTint.R, currentTint.G, currentTint.B, alphaValueForAllPixels);
        //}

        //private Color[] TextureTo2DArray(Texture2D texture)
        //{
        //    Color[] colors1D = new Color[texture.Width * texture.Height];
        //    texture.GetData(colors1D);

        //    return colors1D;

        //    //Color[,] colors2D = new Color[texture.Width, texture.Height];
        //    //for (int x = 0; x < texture.Width; x++)
        //    //    for (int y = 0; y < texture.Height; y++)
        //    //        colors2D[x, y] = colors1D[x + y * texture.Width];

        //    //return colors2D;
        //}

        public override void Draw(GameTime gameTime, SpriteBatch SB)
        {
            //if (_imageIndexToFadeFrom >= 0)
            //{
            //    _imageList[_imageIndexToFadeFrom].Draw(gameTime, SB);
            //}

            _imageList[_currentImageIndex].LoadFromSettings(this.GetBase2DObjectSettings(), SpriteEffects.None, null);
            _imageList[_currentImageIndex].Height = this.Height;
            _imageList[_currentImageIndex].Width = this.Width;
            _imageList[_currentImageIndex].Origin = ConvertGlobalOriginToSpriteOrigin(_currentImageIndex);

            _imageList[_currentImageIndex].Draw(gameTime, SB);
        }
    }
}